//没太理解，你有更好的理解可以把我的删了
/*
中介者模式和观察者模式有一定的相似性，都是一对多的关系，也都是集中式通信，
不同的是中介者模式是处理同级对象之间的交互，而观察者模式是处理Observer和Subject之间的交互。

案例：
一个简单的聊天室，所有的用户都可以发送消息，任何用户发送消息后，聊天室内全成员都收到.
中介者模式角度: 可以使用消息总线抽象不同成员交互(发送消息)，引入第三方消息总线类.
观察者模式角度: 任何一个聊天室内的成员客观上都在监听所有成员发出来的消息. 当然之类消息的订阅者和发布者恰巧是同一类.

*/
//案例1
// 聊天室成员类：
function Member(name) {
    this.name = name;
    this.chatroom = null;
}

Member.prototype = {
    // 发送消息
    send: function (message, toMember) {
        this.chatroom.send(message, this, toMember);
    },
    // 接收消息
    receive: function (message, fromMember) {
        console.log(`${fromMember.name} to ${this.name}: ${message}`);
    }
}
//聊天室类
function Chatroom() {
    this.members = {};
}

Chatroom.prototype = {
    // 增加成员
    addMember: function (member) {
        this.members[member.name] = member;
        member.chatroom = this;
    },
    // 发送消息
    send: function (message, fromMember, toMember) {
        toMember.receive(message, fromMember);
    }
}
const chatroom = new Chatroom();
const bruce = new Member('bruce');
const frank = new Member('frank');

chatroom.addMember(bruce);
chatroom.addMember(frank);

bruce.send('Hey frank', frank);

//案例2
// 中介者
let mediator = (function () {
    let topics = {};

    // 订阅：订阅A组件中的某个方法
    let subscribe = function subscribe(topic, callback) {
        !topics[topic] ? topics[topic] = [] : null;
        topics[topic].push({
            context: this,
            callback
        });
    };

    // 发布：B组件中到某个阶段，可以通知之前订阅的方法执行
    let publish = function publish(topic, ...params) {
        if (!topics[topic]) return;
        topics[topic].forEach(item => {
            let {
                callback,
                context
            } = item;
            callback.call(context, ...params);
        });
    };

    return {
        subscribe,
        publish
    };
})();